package com.tikin.mqtt.service

import android.content.Context
import android.os.Handler
import android.util.Log
import com.google.protobuf.Any
import com.tikin.message.proto.*
import com.tikin.mqtt.MqttManagerOption
import com.tikinmedia.oms.*
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.*

class MqttManager(
    private val applicationContext: Context,
    private val option: MqttManagerOption,
    private val handler:Handler
) {
    private var sendSetWill = false
    companion object {
        private const val TAG = "MqttDispatchService"
    }

    private lateinit var mqttAndroidClient: MqttAndroidClient
    private lateinit var mqttConnectOptions: MqttConnectOptions

    private val mqttActionListener = object : IMqttActionListener {
        override fun onSuccess(asyncActionToken: IMqttToken?) {
            Log.e(TAG, "mqtt - onSuccess ")
            mqttAndroidClient.subscribe(option.topic, option.qos)
        }

        override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
            Log.e(TAG, "mqtt - onFailure ")
            exception?.printStackTrace()
            endClient()
            val msg  = handler.obtainMessage(100)
            handler.sendMessageDelayed(msg,10*1000)
        }
    }

    private val mqttCallback = object : MqttCallback {
        override fun connectionLost(cause: Throwable?) {
            Log.e(TAG, "error: ${cause?.printStackTrace()} ")
        }

        override fun messageArrived(topic: String?, message: MqttMessage?) {
            if (message != null && message.payload != null) {
                //todo  message 解析 action msg
                Log.e(TAG, "Receive message: ${message.toString()} from topic: $topic")
//                EventBus.getDefault().post(MqttMsgArriveEvent("", ""))
                val tkMessage = TransmitMessage.parseFrom(message.payload)
                val header = tkMessage.header
                val body = tkMessage.body
                when {
//                    发刊
                    header.msgAction == MsgHeader.Header.ActionType.CONTRACT && header.msgType == 1 -> {

                    }
//                    下刊
                    header.msgAction == MsgHeader.Header.ActionType.CONTRACT && header.msgType == 2 -> {

                    }

//                    版本更新
                    header.msgAction == MsgHeader.Header.ActionType.SOFTWARE_UPDATE && header.msgType == 0 -> {

                    }
//                    设备重启
                    header.msgAction == MsgHeader.Header.ActionType.BURIED_POINT && header.msgType == 1 -> {

                    }
                }

            }
        }

        override fun deliveryComplete(token: IMqttDeliveryToken?) {
            Log.e(TAG, "deliveryComplet ")
        }
    }

    fun initClient( will: TransmitMessage.Builder) {
        mqttAndroidClient = MqttAndroidClient(applicationContext, option.uri, option.clientId)
        mqttAndroidClient.setCallback(mqttCallback)
        mqttConnectOptions = MqttConnectOptions()
        mqttConnectOptions.isAutomaticReconnect = true
        mqttConnectOptions.isCleanSession = false
        mqttConnectOptions.keepAliveInterval = 60
        mqttConnectOptions.connectionTimeout = 20
        mqttConnectOptions.userName = option.userName
        mqttConnectOptions.password = option.password.toCharArray()
        mqttConnectOptions.setWill(option.topicLoc, will.build().toByteArray(), 1, true)
//        doConnect()
        mqttAndroidClient.connect(mqttConnectOptions, null, mqttActionListener)
        handler.removeMessages(0)
        looper()
        sendSetWill = true
    }
    private fun looper(){
        handler.postDelayed({
            if (!mqttAndroidClient.isConnected){
                val msg  = handler.obtainMessage(100)
                handler.sendMessage(msg)
            }else {
                if (sendSetWill){
                    sendSetWill = false
                    sendWillMessage()
                }
            }
            looper()
        },10*1000)
    }
    fun endClient() {
        mqttAndroidClient.disconnect()
    }

    fun publish(msg: MqttMessage) {
        if (mqttAndroidClient.isConnected) {
            mqttAndroidClient.publish(option.topicLoc, msg)
            Log.e(TAG, "send message")
        }
    }

    private fun sendWillMessage() {
        try {

            val willRetain = WillRetain.MsgWillRetain.newBuilder().setOffline(true).build()

            val header = MsgHeader.Header.newBuilder()
                .setMsgAction(MsgHeader.Header.ActionType.BURIED_POINT)
                .setMsgType(2)
                .build()

            val body = MsgBody.Body.newBuilder().setContent(Any.pack(willRetain)).build()

            val builder = TransmitMessage.newBuilder().setHeader(header).setBody(body).build()

            val mqttMessage = MqttMessage()
            mqttMessage.qos = option.qos[0]
            mqttMessage.isRetained = true
            mqttMessage.payload = builder.toByteArray()

            publish(mqttMessage)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }


}